package com.dodo.blog.model;

import com.dodo.blog.ui.component.input.Renderable;
import com.google.appengine.api.datastore.Blob;

import javax.persistence.Entity;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
 */
@Entity
public class Article
        extends BaseEntity
        implements Renderable
{
    private static final long serialVersionUID = 1L;

    private static final NumberFormat DF = new DecimalFormat( "00" );

    private static final String ARTICLE_ENCODING = "UTF-8";

    @NotNull
    private Long authorId;

    @NotNull
    private String title;

    private String normalizedName;

    @NotNull
    private Blob content;

    private String imageBlobKey;

    @NotNull
    private Long tag_1;

    private Long tag_2;

    private Long tag_3;

    private Long tag_4;

    private Long tag_5;

    @NotNull
    private Long category;

    private String year;

    private String month;

    private String day;

    private Long rateCount = 0L;

    private Long rateTotal = 0L;

    private Double rate = 0D;

    private Long viewed = 0L;

    private Boolean published = Boolean.FALSE;

    private Date publishedDate;

    public Long getAuthorId()
    {
        return authorId;
    }

    public void setAuthorId( Long authorId )
    {
        this.authorId = authorId;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle( String title )
    {
        this.title = title;
        this.normalizedName = title.toLowerCase().replace( " ", "-" );
    }

    public String getContent()
    {
        try
        {
            return new String( content.getBytes(), ARTICLE_ENCODING );
        }
        catch ( Exception e )
        {
            return null;
        }
    }

    public void setContent( String content )
    {
        try
        {
            this.content = new Blob( content.getBytes( "UTF-8" ) );
        }
        catch ( Exception e )
        {
            this.content = null;
        }
    }

    public String getImageBlobKey()
    {
        return imageBlobKey;
    }

    public void setImageBlobKey( String imageBlobKey )
    {
        this.imageBlobKey = imageBlobKey;
    }

    public Long getTag_1()
    {
        return tag_1;
    }

    public void setTag_1( Long tag_1 )
    {
        this.tag_1 = tag_1;
    }

    public Long getTag_2()
    {
        return tag_2;
    }

    public void setTag_2( Long tag_2 )
    {
        this.tag_2 = tag_2;
    }

    public Long getTag_3()
    {
        return tag_3;
    }

    public void setTag_3( Long tag_3 )
    {
        this.tag_3 = tag_3;
    }

    public Long getTag_4()
    {
        return tag_4;
    }

    public void setTag_4( Long tag_4 )
    {
        this.tag_4 = tag_4;
    }

    public Long getTag_5()
    {
        return tag_5;
    }

    public void setTag_5( Long tag_5 )
    {
        this.tag_5 = tag_5;
    }

    public Long getCategory()
    {
        return category;
    }

    public void setCategory( Long category )
    {
        this.category = category;
    }

    public String getYear()
    {
        return year;
    }

    public void setYear( String year )
    {
        this.year = year;
    }

    public String getMonth()
    {
        return month;
    }

    public void setMonth( String month )
    {
        this.month = month;
    }

    public String getDay()
    {
        return day;
    }

    public void setDay( String day )
    {
        this.day = day;
    }

    public void incrementRate( Long rate )
    {
        this.rateCount++;
        this.rateTotal += rate;
        this.rate = calculateRate();
    }

    public Double calculateRate()
    {
        if ( rateCount > 0 )
        {
            return BigDecimal.valueOf( rateTotal ).divide( BigDecimal.valueOf( rateCount ) ).doubleValue();
        }

        return 0D;
    }

    public void incrementViewed()
    {
        this.viewed = this.viewed + 1;
    }

    public Long getViewed()
    {
        return viewed;
    }

    public Double getRate()
    {
        return rate;
    }

    @Override
    public void prePersist()
    {
        super.prePersist();

        Calendar c = Calendar.getInstance();
        c.setTime( getCreatedDate() );

        year = Integer.valueOf( c.get( Calendar.YEAR ) ).toString();
        month = DF.format( c.get( Calendar.MONTH ) + 1 );
        day = DF.format( c.get( Calendar.DAY_OF_MONTH ) );
    }

    public Boolean isPublished()
    {
        return published;
    }

    public void setPublished( Boolean published )
    {
        this.published = published;
    }

    public Date getPublishedDate()
    {
        return publishedDate;
    }

    public void setPublishedDate( Date publishedDate )
    {
        this.publishedDate = publishedDate;
    }

    public String getNormalizedName()
    {
        return normalizedName;
    }

    public void setNormalizedName( String normalizedName )
    {
        this.normalizedName = normalizedName;
    }

    @Override
    public String toString()
    {
        return "Article{" +
                "authorId=" + authorId +
                ", title='" + title + '\'' +
                ", content=" + content +
                ", imageBlobKey='" + imageBlobKey + '\'' +
                ", tag_1=" + tag_1 +
                ", tag_2=" + tag_2 +
                ", tag_3=" + tag_3 +
                ", tag_4=" + tag_4 +
                ", tag_5=" + tag_5 +
                ", category=" + category +
                ", year='" + year + '\'' +
                ", month='" + month + '\'' +
                ", day='" + day + '\'' +
                ", rateCount=" + rateCount +
                ", rateTotal=" + rateTotal +
                ", published=" + published +
                ", publishedDate=" + publishedDate +
                '}';
    }

    @Override
    public String getLabel()
    {
        return getTitle();
    }
}
